package com.yanti.strategy.impl;

import cn.hutool.core.lang.UUID;
import com.yanti.config.minio.MinioProperties;
import com.yanti.domain.enums.AppHttpCodeEnum;
import com.yanti.domain.exception.BizException;
import com.yanti.strategy.FileStrategy;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.util.Objects;


@Slf4j
public class MinioFileStrategy implements FileStrategy {

    @Resource
    private MinioProperties minioProperties;

    @Resource
    private MinioClient minioClient;

    @Override
    public String uploadFile(MultipartFile file, String bucketName){
        log.info("## 上传文件至 Minio ...");
        // 判断文件是否为空
        if (file == null || file.getSize() == 0) {
            log.error("==> 上传文件异常：文件大小为空 ...");
            throw new BizException(AppHttpCodeEnum.FILE_UPLOAD_ERROR);
        }
        String url = null;
        try {
            // 文件的原始名称
            String originalFileName = file.getOriginalFilename();
            // 文件的 Content-Type
            String contentType = file.getContentType();

            // 生成存储对象的名称（将 UUID 字符串中的 - 替换成空字符串）
            String key = UUID.randomUUID().toString().replace("-", "");
            // 获取文件的后缀，如 .jpg
            String suffix = Objects.requireNonNull(originalFileName).substring(originalFileName.lastIndexOf("."));

            // 拼接上文件后缀，即为要存储的文件名
            String objectName = String.format("%s%s", key, suffix);

            log.info("==> 开始上传文件至 Minio, ObjectName: {}", objectName);

            // 上传文件至 Minio
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .contentType(contentType)
                    .build());

            // 返回文件的访问链接
            url = String.format("%s/%s/%s", minioProperties.getEndpoint(), bucketName, objectName);
            log.info("==> 上传文件至 Minio 成功，访问路径: {}", url);
            return url;
        } catch (Exception e) {
            log.error("Minio文件上传失败", e);
            throw new BizException(AppHttpCodeEnum.FILE_UPLOAD_ERROR);
        }
    }
}